/**
 * Created by cb on 15/3/31.
 */
var __extends = this.__extends || function(d, b) {
	for ( var p in b)
		if (b.hasOwnProperty(p))
			d[p] = b[p];
	function __() {
		this.constructor = d;
	}
	__.prototype = b.prototype;
	d.prototype = new __();
};
// Production steps of ECMA-262, Edition 5, 15.4.4.18
// Reference: http://es5.github.io/#x15.4.4.18
if (!Array.prototype.forEach) {
	Array.prototype.forEach = function(callback, thisArg) {
		var T, k;
		if (this == null) {
			throw new TypeError(' this is null or not defined');
		}
		// 1. Let O be the result of calling ToObject passing the |this| value
		// as the argument.
		var O = Object(this);
		// 2. Let lenValue be the result of calling the Get internal method of O
		// with the argument "length".
		// 3. Let len be ToUint32(lenValue).
		var len = O.length >>> 0;
		// 4. If IsCallable(callback) is false, throw a TypeError exception.
		// See: http://es5.github.com/#x9.11
		if (typeof callback !== "function") {
			throw new TypeError(callback + ' is not a function');
		}
		// 5. If thisArg was supplied, let T be thisArg; else let T be
		// undefined.
		if (arguments.length > 1) {
			T = thisArg;
		}
		// 6. Let k be 0
		k = 0;
		while (k < len) {
			var kValue;
			// a. Let Pk be ToString(k).
			// This is implicit for LHS operands of the in operator
			// b. Let kPresent be the result of calling the HasProperty internal
			// method of O with argument Pk.
			// This step can be combined with c
			// c. If kPresent is true, then
			if (k in O) {
				// i. Let kValue be the result of calling the Get internal
				// method of O with argument Pk.
				kValue = O[k];
				// ii. Call the Call internal method of callback with T as the
				// this value and
				// argument list containing kValue, k, and O.
				callback.call(T, kValue, k, O);
			}
			// d. Increase k by 1.
			k++;
		}
		// 8. return undefined
	};
}
// Production steps of ECMA-262, Edition 5, 15.4.4.14
// Reference: http://es5.github.io/#x15.4.4.14
if (!Array.prototype.indexOf) {
	Array.prototype.indexOf = function(searchElement, fromIndex) {
		var k;
		// 1. Let O be the result of calling ToObject passing
		// the this value as the argument.
		if (this == null) {
			throw new TypeError('"this" is null or not defined');
		}
		var O = Object(this);
		// 2. Let lenValue be the result of calling the Get
		// internal method of O with the argument "length".
		// 3. Let len be ToUint32(lenValue).
		var len = O.length >>> 0;
		// 4. If len is 0, return -1.
		if (len === 0) {
			return -1;
		}
		// 5. If argument fromIndex was passed let n be
		// ToInteger(fromIndex); else let n be 0.
		var n = +fromIndex || 0;
		if (Math.abs(n) === Infinity) {
			n = 0;
		}
		// 6. If n >= len, return -1.
		if (n >= len) {
			return -1;
		}
		// 7. If n >= 0, then Let k be n.
		// 8. Else, n<0, Let k be len - abs(n).
		// If k is less than 0, then let k be 0.
		k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
		while (k < len) {
			// a. Let Pk be ToString(k).
			// This is implicit for LHS operands of the in operator
			// b. Let kPresent be the result of calling the
			// HasProperty internal method of O with argument Pk.
			// This step can be combined with c
			// c. If kPresent is true, then
			// i. Let elementK be the result of calling the Get
			// internal method of O with the argument ToString(k).
			// ii. Let same be the result of applying the
			// Strict Equality Comparison Algorithm to
			// searchElement and elementK.
			// iii. If same is true, return k.
			if (k in O && O[k] === searchElement) {
				return k;
			}
			k++;
		}
		return -1;
	};
}
// 被观察者的基类
var ConcreteSubject = (function() {
	function ConcreteSubject() {
		this.observers = [];
	}
	ConcreteSubject.prototype.addObserver = function(observer) {
		this.observers.push(observer);
	};
	ConcreteSubject.prototype.removeObserver = function(observer) {
		var key = -1;
		if ((key = this.observers.indexOf(observer)) != -1)
			this.observers.splice(key, 1);
	};
	ConcreteSubject.prototype.update = function(targer) {
		try {
			this.observers.forEach(function(o) {
				o.update(targer);
			});
		} catch ($e) {
			throw "请子类constructor 使用 super() 继承父类";
		}
	};
	return ConcreteSubject;
})();
// 修改数量
var NumberChange = (function(_super) {
	__extends(NumberChange, _super);
	function NumberChange(context) {
		_super.call(this);
		this.config = {
			min : null,
			max : null
		};
		this.bindHandles(context);
		return this;
	}
	// 设置最小数量
	NumberChange.prototype.setMin = function(num) {
		if (num === void 0) {
			num = 1;
		}
		this.config.min = num;
		return this;
	};
	NumberChange.prototype.bindHandles = function(contexts) {
		var _this = this;
		contexts.each(function(i, o) {
			_this.bindHandle($(o));
		});
	};
	NumberChange.prototype.bindHandle = function(context) {
		var _this = this;
		context.find('.cart-num-plus').bind('click', function() {
			_this.plusNumber(context);
		});
		context.find('.cart-num-minus').bind('click', function() {
			_this.minusNumber(context);
		});
		context.find('input').bind('keyup', function() {
			_this.update($(this).val());
		});
	};
	NumberChange.prototype.plusNumber = function(context) {
		this.changeNumber(context.find('input'), 1, context);
	};
	NumberChange.prototype.minusNumber = function(context) {
		this.changeNumber(context.find('input'), -1, context);
	};
	NumberChange.prototype.changeNumber = function(input, nSpec, context) {
		var number = parseInt(input.val());
		number = isNaN(number) ? Math.abs(nSpec) : this.checnedCycle(number
				+ nSpec) ? number + nSpec : number;
		input.val(number);
		this.update(number);
	};
	NumberChange.prototype.checnedCycle = function(num) {
		return typeof this.config.min == 'number'
				&& typeof this.config.max == 'number' ? (num >= this.config.min && num <= this.config.max)
				: (typeof this.config.min == 'number' ? num >= this.config.min
						: (typeof this.config.max == 'number' ? num <= this.config.max
								: true));
	};
	return NumberChange;
})(ConcreteSubject);
/**
 * 弹出层分装 需要插件 artDialog.js css样式 artDialog.css
 */
var oDialog = {
	_show : function(oDialog, backdrop) {
		if (backdrop === void 0) {
			backdrop = true;
		}
		if (backdrop) {
			oDialog.showModal();
		} else {
			oDialog.show();
		}
		return oDialog;
	},
	_extendConfig : function(config) {
		return $.extend({}, {
			backdropBackground : '#000'
		}, config);
	},
	// 弹出框
	alert : function(message, title, backdrop) {
		if (title === void 0) {
			title = '提示';
		}
		if (backdrop === void 0) {
			backdrop = false;
		}
		if (arguments.length == 2) {
			if (typeof title == 'boolean') {
				backdrop = title;
				title = '提示';
			}
		}
		var d = dialog(this._extendConfig({
			title : title,
			content : message,
			okValue : '确定',
			ok : function() {
				return true;
			},
			cancel : false
		}));
		return this._show(d, backdrop);
	},
	loading : function() {
		var f = $("<div class='loading-fixed'></div>").appendTo("body").css({
			position : "fixed",
			width : "100%",
			height : "100%",
			top : 0,
			left : 0,
			zIndex : 99999
		});
		$("<div></div>").appendTo(f).css({
			position : "absolute",
			width : "100%",
			height : "100%",
			top : 0,
			left : 0,
			backgroundColor : "#000",
			filter : "alpha(opacity=70)",
			opacity : 0.7
		});
		var loading = $("<img src='../resources/images/loading-0.gif' />")
				.appendTo(f); // 这里需要修改下图片路径
		loading.css({
			position : "absolute",
			top : $(window).height() / 2 - loading.height() / 2,
			left : $(window).width() / 2 - loading.width() / 2
		});
	},
	offloading : function() {
		$(".loading-fixed").remove();
	},
	// 提示
	prompt : function(message, time, backdrop,timeoutfunc) {
		if (time === void 0) {
			time = 1500;
		}
		if (backdrop === void 0) {
			backdrop = false;
		}
		if (arguments.length == 2) {
			if (typeof time == 'boolean') {
				backdrop = time;
				time = 1500;
			}
		}
		var d = dialog(this._extendConfig({
			content : message
		}));
		setTimeout(function() {
			d.close().remove();
			if(timeoutfunc)
			timeoutfunc();
		}, time);
		return this._show(d, backdrop);
	},
	// 确定框
	confirm : function(content, surFn, cancelFn, title, backdrop) {
		if (title === void 0) {
			title = '提示';
		}
		if (backdrop === void 0) {
			backdrop = true;
		}
		switch (arguments.length) {
		case 2:
			if (typeof surFn == 'boolean') {
				backdrop = surFn;
				surFn = null;
			}
			break;
		case 3:
			if (typeof cancelFn == 'boolean') {
				backdrop = cancelFn;
				cancelFn = null;
			}
			break;
		case 4:
			if (typeof title == 'boolean') {
				backdrop = title;
				title = '提示';
			}
			break;
		}
		var d = dialog(this._extendConfig({
			title : title,
			content : content || '',
			okValue : '确定',
			cancelValue : '取消',
			ok : function() {
				if (surFn)
					surFn();
			},
			cancel : function() {
				if (cancelFn)
					cancelFn();
			}
		}));
		return this._show(d, backdrop);
	},
	// 等待
	wait : function(title, backdrop) {
		if (backdrop === void 0) {
			backdrop = true;
		}
		if (typeof title == 'boolean') {
			backdrop = title;
			title = false;
		}
		var d = dialog(this._extendConfig({
			cancel : false
		}));
		if (title)
			d.title(title);
		return this._show(d, backdrop);
	},
	// 弹出指定id的节点
	dialogElem : function(options, backdrop) {
		if (backdrop === void 0) {
			backdrop = true;
		}
		if (typeof options == 'boolean') {
			backdrop = options;
			options = {};
		}
		if (!options.backdropBackground)
			options.backdropBackground = '#000';
		var d = dialog(this._extendConfig(options));
		return this._show(d, backdrop);
	}
};
/**
 * 倒计时
 */
var CountDown = (function() {
	/**
	 * [constructor description]
	 * 
	 * @param {number =
	 *            120} time [运行时间]
	 * @param {number =
	 *            1000} interval [运行间隔]
	 */
	function CountDown(time, interval) {
		if (time === void 0) {
			time = 120;
		}
		if (interval === void 0) {
			interval = 1000;
		}
		this._isRun = false;
		this._timer = null;
		this.interval = 10000;
		this.timer = time;
		this.process = null; // 倒计时过程执行函数
		this.end = null; // 结束时调用
		this.start = null; // 开始时调用
		this.time = time;
		this.interval = interval;
	}
	CountDown.prototype.run = function() {
		if (this._isRun)
			return false;
		this._isRun = true;
		var _this = this, time = this.time;
		if (this.start)
			this.start(time);
		this._timer = setInterval(function() {
			time--;
			if (time <= 0) {
				_this.stop();
			}
			if (_this.process)
				_this.process(time);
		}, this.interval);
	};
	CountDown.prototype.stop = function() {
		if (this._timer) {
			clearInterval(this._timer);
		}
		this._isRun = false;
		if (this.end)
			this.end();
	};
	CountDown.prototype.isRun = function() {
		return this._isRun;
	};
	return CountDown;
})();
/**
 * 购物车项类
 */
var CartItem = (function() {
	/**
	 * @param number
	 *            id 购物车项ID
	 * @param {number}
	 *            num 数量
	 * @param {number}
	 *            price 价格
	 */
	function CartItem(id, num, price, name, img) {
		if (name === void 0) {
			name = "";
		}
		if (img === void 0) {
			img = '';
		}
		this._cartItemId = id;
		this._totalNumber = num;
		this._price = price;
		this._name = name;
		this._img = img;
	}
	CartItem.prototype.getId = function() {
		return this._cartItemId;
	};
	CartItem.prototype.getName = function() {
		return this._name;
	};
	CartItem.prototype.getImg = function() {
		return this._img;
	};
	CartItem.prototype.changeTotalNumber = function(num) {
		this._totalNumber = num;
	};
	CartItem.prototype.getTotalAmount = function() {
		return this._totalAmount = this._countTotalAmount();
	};
	CartItem.prototype.getTotalNumber = function() {
		return this._totalNumber;
	};
	CartItem.prototype._countTotalAmount = function() {
		return this._totalNumber * this._price;
	};
	return CartItem;
})();
/**
 * 购物车类
 */
var Cart = (function(_super) {
	__extends(Cart, _super);
	function Cart() {
		_super.apply(this, arguments);
		this._tmpCartItems = []; // 临时购物车集合 做逻辑移除时放入临时里面
		this._cartItems = []; // 购物车项集合
	}
	/**
	 * 添加到临时购物车集合里面
	 * 
	 * @param {any}
	 *            cartItem 购物车项
	 */
	Cart.prototype.addTmpCartItem = function(cartItem) {
		this._addCartItemToTarget(cartItem, this._tmpCartItems);
	};
	/**
	 * 从临时集合里面移除
	 * 
	 * @param {any}
	 *            cartItem 购物车项
	 */
	Cart.prototype.removeTmpCartITem = function(cartItem) {
		this._removeCartItemFromTarget(cartItem, this._tmpCartItems);
	};
	/**
	 * 把临时集合里的购物车项全部移入到购物车里
	 */
	Cart.prototype.tmpCartToCart = function() {
		this.addCartItem(this._tmpCartItems);
	};
	/**
	 * 把集合里的购物车项全部移入到临时购物车里
	 */
	Cart.prototype.cartToTmpCart = function() {
		this.removeCartItem(this._cartItems);
	};
	/**
	 * 逻辑删除购物车项 移入到临时集合
	 * 
	 * @param {any}
	 *            cartItem 购物车项
	 */
	Cart.prototype.removeCartItem = function(cartItem) {
		this.addTmpCartItem(cartItem);
		this._removeCartItemFromTarget(cartItem, this._cartItems);
		this.update(this);
	};
	/**
	 * 如果临时集合里面存在此购物车项 则 移除购物车项 移入到购物车集合里
	 * 
	 * @param {any}
	 *            cartItem 购物车项
	 */
	Cart.prototype.addCartItem = function(cartItem) {
		this._addCartItemToTarget(cartItem, this._cartItems);
		this.removeTmpCartITem(cartItem);
		this.update(this);
	};
	/**
	 * 物理删除购物车项 从购物车里彻底移除购物车项
	 * 
	 * @param {any}
	 *            cartItem 购物车项
	 */
	Cart.prototype.deleteCartItem = function(cartItem) {
		this.removeCartItem(cartItem);
		this.removeTmpCartITem(cartItem);
	};
	/**
	 * 获取购物车集合
	 */
	Cart.prototype.getCartItems = function() {
		return this._cartItems;
	};
	/**
	 * 获取总金额
	 * 
	 * @return {number} [description]
	 */
	Cart.prototype.getTotalAmount = function() {
		return this._totalAmount = this._countTotalAmount();
	};
	/**
	 * 获取购物车数量
	 * 
	 * @return {number} [description]
	 */
	Cart.prototype.getTotalNumber = function() {
		return this._cartItems.length;
	};
	/**
	 * 添加购物车项到指定的数组
	 * 
	 * @param {CartItem}
	 *            cartItem [description]
	 * @param {[CartItem]}
	 *            target _tmpCartItems 或 _cartItems
	 */
	Cart.prototype._addCartItemToTarget = function(cartItem, target) {
		if (!~target.indexOf(cartItem)) {
			if ($.isArray(cartItem)) {
				cartItem.forEach(function(o) {
					target.push(o);
				});
			} else {
				target.push(cartItem);
			}
		}
		return target;
	};
	/**
	 * 从指定的集合移除购物车项
	 * 
	 * @param {CartItem}
	 *            cartItem 购物车项 可以是数组
	 * @param {[CartItem]}
	 *            target _tmpCartItems 或 _cartItems
	 */
	Cart.prototype._removeCartItemFromTarget = function(cartItem, target) {
		var _this = this;
		if (target.length) {
			if ($.isArray(cartItem) && cartItem.length) {
				_this._removeSingleCartItemFromTarget(cartItem[0], target);
				_this._removeCartItemFromTarget(cartItem, target);
			} else {
				this._removeSingleCartItemFromTarget(cartItem, target);
			}
		}
		return target;
	};
	/**
	 * 从指定的集合移除单个购物车项
	 * 
	 * @param {CartItem}
	 *            cartItem 购物车项
	 */
	Cart.prototype._removeSingleCartItemFromTarget = function(cartItem, target) {
		if (target.length) {
			var index = target.indexOf(cartItem);
			if (~index) {
				target.splice(index, 1);
			}
		}
		return target;
	};
	/**
	 * 计算购物车集合里面的总金额
	 * 
	 * @return {number} [description]
	 */
	Cart.prototype._countTotalAmount = function() {
		var amount = 0;
		this._cartItems.forEach(function(oCartItem) {
			amount += oCartItem.getTotalAmount();
		});
		return amount;
	};
	return Cart;
})(ConcreteSubject);
/**
 * 分页
 */
var PageDom = (function(_super) {
	__extends(PageDom, _super);
	function PageDom() {
		_super.call(this);
		this._wrap = null;
	}
	PageDom.prototype.pageBtn = function(page) {
		var e;
		if (page == this.current) {
			e = $('<span></span>').addClass('current');
		} else {
			e = $('<a href="javascript:;"></a>');
			var _this = this;
			e.click(function() {
				_this.update(page);
				_this.current = page;
				_this._wrap.children().remove();
				_this._appendPage();
			});
		}
		e.text(page);
		return e;
	};
	PageDom.prototype.config = function(total, perPage, current) {
		if (current === void 0) {
			current = 1;
		}
		this._total = total;
		this._perPage = perPage;
		this._pageNumber = Math.ceil(this._total / this._perPage);
		this.current = current;
	};
	PageDom.prototype.showPage = function() {
		this._createWrap();
		this._appendPage();
		return $('<div><div>').addClass('rate-page').append(this._wrap);
	};
	PageDom.prototype.removePage = function() {
		if (this._wrap) {
			this._wrap.parent().remove();
			this._wrap = null;
		}
	};
	PageDom.prototype._appendPage = function() {
		var pageBtns = this._createPage(), page = this._wrap;
		pageBtns.forEach(function(o) {
			page.append(o);
		});
	};
	PageDom.prototype._createWrap = function() {
		return this._wrap = $('<div></div>').addClass('rate-paginator');
	};
	PageDom.prototype._createPage = function() {
		var pages = [];
		pages.push(this.prevBtn());
		if (this.current == 1) {
			var t = this._pageNumber < 3 ? this._pageNumber : 3;
			for (var i = 1; i <= t; i++) {
				pages.push(this.pageBtn(i));
			}
			if (this._pageNumber > 3)
				pages.push(this.breakBtn());
		} else if (this.current <= 5) {
			for (var i = 1; i <= (this.current + 1 > this._pageNumber ? this._pageNumber
					: this.current + 1); i++) {
				pages.push(this.pageBtn(i));
			}
		} else {
			var t = this.current + 1 > this._pageNumber ? this._pageNumber
					: this.current + 1;
			for (var i = 1; i < 3; i++) {
				pages.push(this.pageBtn(i));
			}
			pages.push(this.breakBtn());
			for (var i = t - 3; i <= t; i++) {
				var page = this.pageBtn(i);
				if (i == t - 3) {
					page.addClass('has-left-border');
				}
				if (i == t) {
					page.addClass('no-right-border');
				}
				pages.push(page);
			}
		}
		pages.push(this.nextBtn());
		return pages;
	};
	PageDom.prototype.breakBtn = function() {
		return $('<span></span>').addClass('rate-page-break').text('...');
	};
	PageDom.prototype.prevBtn = function() {
		var page = this.pageBtn(this.current - 1 > 1 ? this.current - 1 : 1);
		return page.text('<<上一页').addClass('rate-page-prev');
	};
	PageDom.prototype.nextBtn = function() {
		var page = this
				.pageBtn(this.current + 1 <= this._pageNumber ? this.current + 1
						: this._pageNumber);
		return page.text('下一页>>').addClass('rate-page-next');
	};
	return PageDom;
})(ConcreteSubject);
/**
 * 基础的ajax请求类
 */
var BaseAjax = (function() {
	function BaseAjax() {
		this._defaultConfig = {
			url : '',
			data : {},
			cache : true,
			dataType : 'json',
			method : 'get',
			beforeSend : this.beforeSend.call(this),
			success : this.success.call(this),
			error : this.error.call(this),
			complete : this.complete.call(this)
		};
	}
	BaseAjax.prototype.beforeSend = function() {
	};
	BaseAjax.prototype.success = function(data) {
	};
	BaseAjax.prototype.error = function() {
	};
	BaseAjax.prototype.complete = function() {
	};
	BaseAjax.prototype.setConfig = function(config) {
		this._defaultConfig = $.extend({}, this._defaultConfig, config);
	};
	BaseAjax.prototype.http = function() {
		return $.ajax(this._defaultConfig);
	};
	return BaseAjax;
})();
/**
 * 数据存储 如果支持本地存储 将调用 localStorage 否则使用 cookie 默认过期时间为365天 使用cookie 则依赖
 * jquery.cookie.js
 */
var oStorage = (function() {
	var storage = null, tools = null;
	if (window.localStorage) {
		storage = window.localStorage;
		tools = {
			add : function(name, data) {
				return storage[name] = data;
			},
			get : function(name) {
				return storage[name];
			},
			del : function(name) {
				if (storage.removeItem(name))
					return true;
				else
					return false;
			}
		}
	} else {
		storage = $.cookie;
		tools = {
			add : function(name, data, expires) {
				return storage(name, data, {
					expires : expires || 365
				});
			},
			get : function(name) {
				return storage(name);
			},
			del : function() {
				if (storage(name, '', {
					expires : -1
				}))
					return true;
				else
					return false;
			}
		}
	}
	return function() {
		return tools;
	}
})();

var searchHistoryManage = (function(sHistoryName) {

	return function(name) {
		return new History(name || sHistoryName);
	};

	function History(name) {
		this.getName = function() {
			return name;
		};
		/**
		 * 获取数据 如果数据部存在则 返回默认格式的空数据
		 */
		this.get = function() {
			if (oStorage().get(name)) {
				return JSON.parse(oStorage().get(name));
			}
			return {
				list : []
			};
		};
		/**
		 * 添加数据
		 * 
		 * @param string
		 *            name
		 * @param url
		 */
		this.add = function(data) {
			var oHistory = this.get(), nLen = oHistory.list.length, bStop = false;
			for (var i = 0; i < nLen; i++) {
				if (oHistory.list[i]['name'] == data.name) {
					oHistory.list[i]['result'] = oHistory.list[i]['value'] = data.name;
					oHistory.list[i]['data'] = data;
					oHistory.list.unshift(oHistory.list.splice(i, 1)[0]);
					bStop = true;
					break;
				}
			}
			if (!bStop) {
				if (oHistory.list.length >= 10) {
					oHistory.list.pop();
				}
				oHistory.list.unshift({
					name : data.name,
					result : data.name,
					value : data.name,
					data : data
				});
			}
			oStorage().add(this.getName(), JSON.stringify(oHistory));
		};
		/**
		 * 删除指定名称的数据
		 */
		this.del = function(name) {
			var oHistory = this.get(), nLen = oHistory.list.length;
			for (var i = 0; i < nLen; i++) {
				if (oHistory.list[i]['name'] == name) {
					oHistory.list.splice(i, 1);
					break;
				}
			}
			oStorage().add(this.getName(), JSON.stringify(oHistory))
		}
	}
})('history');